package Controller;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import java.util.*;

// 在区域内部运行的AreaController
public class AreaController extends Thread{
    String name;
    Map<String, Router> routerMap;
    ArrayList<Router> borderRouterList;
    Map<PositionTuple, PositionTuple> topology;
    String host;
    int port;

    public AreaController(){
        routerMap = new HashMap<>();
        borderRouterList = new ArrayList<>();
        topology = new HashMap<>();
    }

    public void addTopology(PositionTuple p1, PositionTuple p2){
        topology.put(p1, p2);
        topology.put(p2, p1);
        p1.router.topology.put(p1, p2);
        p2.router.topology.put(p2, p1);

    }
    public AreaController(String path){
        this();
        try {
            readConfig(path);
        }catch (FileNotFoundException e){
            System.err.printf("file path:%s is not exists.\n", path);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void readConfig(String path) throws IOException, ArrayIndexOutOfBoundsException {
        Properties pps = new Properties();
        pps.load(new FileInputStream(path));
        for(String key:pps.stringPropertyNames()){
            if(key.equals("name")){
                name = pps.getProperty(key);
            }else if(key.equals("host")){
                host = pps.getProperty(key);
            }else if(key.equals("port")){
                port = Integer.parseInt(pps.getProperty(key));
            }else if(key.startsWith("router")){
                String[] token = pps.getProperty(key).split("\\s+");
                Router r = new Router(token[0], token[1], token[2]);
                routerMap.put(r.name, r);
            }else if(key.startsWith("outRouter")){
                String[] token = pps.getProperty(key).split("\\s+");
                Router r = new Router(token[0], token[1]);
                routerMap.put(r.name, r);
            }else if(key.startsWith("topology")){
                String[] token = pps.getProperty(key).split("\\s+");
                Router r1 = routerMap.get(token[0]);
                Router r2 = routerMap.get(token[3]);
                PositionTuple p1 = new PositionTuple(r1, token[1], token[2]);
                PositionTuple p2 = new PositionTuple(r2, token[4], token[5]);
                addTopology(p1, p2);
            }

        }
    }


    public void run(){
        ServerSocket server;
        try {
            server = new ServerSocket(port, 50, InetAddress.getByName(host));
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        while (true){
            try {
                Socket s = server.accept();

            } catch (IOException ignored){
            }
        }

    }

    private static class Router{
        public String name;
        public String host;
        public int comPort;
        public RouterType type;
        Map<PositionTuple, PositionTuple> topology;

        public Router(){
            topology = new HashMap<>();
        }

        public Router(String name, String host){
            this();
            this.name = name;
            this.host = host;
            type = RouterType.OutRouter;

        }

        public Router(String name, String host, String comPort){
            this();
            this.name = name;
            this.host = host;
            this.comPort = Integer.parseInt(comPort);
            type = RouterType.Router;
        }

        public Router(String name, String host, int comPort){
            this();
            this.name = name;
            this.host = host;
            this.comPort = comPort;
            type = RouterType.Router;
        }

        public static enum RouterType{
            Router, BorderRouter, OutRouter
        }
    }

    private static class PositionTuple{
        public Router router;
        public String port;
        public int socketPort;

        public PositionTuple(Router router, String port, int socketPort){
            this.router = router;
            this.port = port;
            this.socketPort = socketPort;
        }

        public PositionTuple(Router router, String port, String socketPort){
            this.router = router;
            this.port = port;
            this.socketPort = Integer.parseInt(socketPort);
        }
    }
}
